home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 3 code / Meet PrGeneral / PrGeneralPlay.c next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  18.6 KB  |  675 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    PrGeneralPlay.c
  4. #
  5. #    PrGeneralPlay is an example application that demonstrates the use
  6. #     of PrGeneral's opcodes: GetRslData, SetRsl, GetRotn, DraftBits, and 
  7. #   NoDraftBits.  For complete details about the functionality of this
  8. #    application, see the header at the top of the PrGeneralPlayPrint.c file.
  9. #
  10. # ------------------------------------------------------------------------------  
  11. #
  12. #    Versions:   1.00                    June 1, 1990
  13. #
  14. #    Components: PrGeneralPlay.c            June 1, 1990
  15. #                PrGeneralPlayPrint.c    June 1, 1990
  16. #                PrGeneralPlay.h            June 1, 1990
  17. #                PrGeneralPlay.r            June 1, 1990
  18. #
  19. #
  20. #    Apple Macintosh Developer Technical Support
  21. #    Copyright © 1990 Apple Computer, Inc.
  22. #    All rights reserved.
  23. #
  24. ------------------------------------------------------------------------------*/
  25.  
  26. #include <Values.h>
  27. #include <Types.h>
  28. #include <Resources.h>
  29. #include <QuickDraw.h>
  30. #include <Fonts.h>
  31. #include <Events.h>
  32. #include <Windows.h>
  33. #include <Menus.h>
  34. #include <TextEdit.h>
  35. #include <Dialogs.h>
  36. #include <Desk.h>
  37. #include <ToolUtils.h>
  38. #include <Memory.h>
  39. #include <SegLoad.h>
  40. #include <Files.h>
  41. #include <OSUtils.h>
  42. #include <OSEvents.h>
  43. #include <DiskInit.h>
  44. #include <Packages.h>
  45. #include <Traps.h>
  46. #include <Printing.h>
  47. #include <PrGeneralPlay.h>        /* bring in all of the #defines for PrGeneralPlay */
  48.  
  49. #define        QD32Trap            0xAB03
  50. #define        Unimplemented        0xA89F
  51.  
  52.  
  53. SysEnvRec    gMac;                /* set up by Initialize */
  54. Boolean        gHasWaitNextEvent;    /* set up by Initialize */
  55.  
  56. THPrint        gPrRecHdl;
  57.  
  58. Boolean        gHighResolutionON,   /**  These globals are set up by Initialize  **/
  59.             gUseDraftBits,
  60.             gCheckForLandscape,
  61.             gDraftBitsHasBeenSet;
  62.             gPrGeneralLives,
  63.             gLandscapeOpImpl,
  64.             gDraftBitsOpImpl,
  65.             gSetRslOpImpl;
  66.  
  67. short        gOriginalDriverVers;
  68.  
  69.  
  70. /* Here are declarations for all of the C routines. In MPW 3.0 we can use
  71.    actual prototypes for parameter type checking. */
  72. void EventLoop( void );
  73. void DoEvent( EventRecord *event );
  74. void GetGlobalMouse( Point *mouse );
  75. void AdjustMenus( void );
  76. void DoMenuCommand( long menuResult );
  77. void Terminate( void );
  78. void Initialize( void );
  79. void ForceEnvirons( void );
  80. Boolean IsDAWindow( WindowPtr window );
  81. Boolean TrapAvailable( short tNumber, TrapType tType );
  82. void AlertUser( void );
  83. void QD32BitAlertUser ( void );
  84.  
  85. extern Boolean testForPrGeneral ( void );
  86. extern void noPrGeneralAlert ( void );
  87.  
  88.  
  89. /* Define HiWrd and LoWrd macros for efficiency. */
  90. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  91. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  92.  
  93. /* Define TopLeft and BotRight macros for convenience. Notice the implicit
  94.    dependency on the ordering of fields within a Rect */
  95. #define TopLeft(aRect)    (* (Point *) &(aRect).top)
  96. #define BotRight(aRect)    (* (Point *) &(aRect).bottom)
  97.  
  98.  
  99. extern void _DataInit();
  100.  
  101. /* This routine is part of the MPW runtime library. This external
  102.    reference to it is done so that we can unload its segment, %A5Init. */
  103.  
  104.  
  105. #pragma segment Main
  106. main()
  107. {
  108.     UnloadSeg((Ptr) _DataInit);        /* note that _DataInit must not be in Main! */
  109.     
  110.     /* 1.01 - call to ForceEnvirons removed */
  111.     
  112.     /*    If you have stack requirements that differ from the default,
  113.         then you could use SetApplLimit to increase StackSpace at 
  114.         this point, before calling MaxApplZone. */
  115.     MaxApplZone();                    /* expand the heap so code segments load at the top */
  116.  
  117.     Initialize();                    /* initialize the program */
  118.     UnloadSeg((Ptr) Initialize);    /* note that Initialize must not be in Main! */
  119.  
  120.     EventLoop();                    /* call the main event loop */
  121. }
  122.  
  123.  
  124. /*    Get events forever, and handle them by calling DoEvent.
  125.     Get the events by calling WaitNextEvent, if it's available, otherwise
  126.     by calling GetNextEvent.  */
  127.  
  128. #pragma segment Main
  129. void EventLoop()
  130. {
  131.     RgnHandle    cursorRgn;
  132.     Boolean        gotEvent;
  133.     EventRecord    event;
  134.  
  135.     cursorRgn = NewRgn();            /* we’ll pass WNE an empty region the 1st time thru */
  136.     do {
  137.         /* use WNE if it is available */
  138.         if ( gHasWaitNextEvent )             
  139.           gotEvent = WaitNextEvent(everyEvent, &event, 30, cursorRgn);
  140.         else {
  141.             SystemTask();
  142.             gotEvent = GetNextEvent(everyEvent, &event);
  143.         }
  144.         
  145.         if ( gotEvent ) DoEvent(&event);
  146.  
  147.           } while ( true );    /* loop forever; we quit via ExitToShell */
  148. } /*EventLoop*/
  149.  
  150.  
  151. /* Do the right thing for an event. Determine what kind of event it is, and call
  152.  the appropriate routines. */
  153.  
  154. #pragma segment Main
  155. void DoEvent(event)
  156.     EventRecord    *event;
  157. {
  158.     short        part, err;
  159.     WindowPtr    window;
  160.     Boolean        hit;
  161.     char        key;
  162.     Point        aPoint;
  163.  
  164.     switch ( event->what ) {
  165.         case mouseDown:
  166.             part = FindWindow(event->where, &window);
  167.             switch ( part ) {
  168.                 case inMenuBar:                /* process a mouse menu command (if any) */
  169.                     AdjustMenus();
  170.                     DoMenuCommand(MenuSelect(event->where));
  171.                     break;
  172.                 case inSysWindow:            /* let the system handle the mouseDown */
  173.                     SystemClick(event, window);
  174.                     break;
  175.                 case inContent:
  176.                     break;
  177.                 case inDrag:                /* pass screenBits.bounds to get all gDevices */
  178.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  179.                     break;
  180.                 case inGrow:
  181.                     break;
  182.                 case inZoomIn:
  183.                 case inZoomOut:
  184.                     hit = TrackBox(window, event->where, part);
  185.                     if ( hit ) {
  186.                         SetPort(window);                /* the window must be the current port... */
  187.                         EraseRect(&window->portRect);    /* because of a bug in ZoomWindow */
  188.                         ZoomWindow(window, part, true);    /* note that we invalidate and erase... */
  189.                         InvalRect(&window->portRect);    /* to make things look better on-screen */
  190.                     }
  191.                     break;
  192.             }
  193.             break;
  194.         case keyDown:
  195.         case autoKey:                        /* check for menukey equivalents */
  196.             key = event->message & charCodeMask;
  197.             if ( event->modifiers & cmdKey )            /* Command key down */
  198.                 if ( event->what == keyDown ) {
  199.                     AdjustMenus();                        /* enable/disable/check menu items properly */
  200.                     DoMenuCommand(MenuKey(key));
  201.                 }
  202.             break;
  203.         case activateEvt:
  204.             break;
  205.         case updateEvt:
  206.             break;
  207.         /*    1.01 - It is not a bad idea to at least call DIBadMount in response
  208.             to a diskEvt, so that the user can format a floppy. */
  209.         case diskEvt:
  210.             if ( HiWord(event->message) != noErr ) {
  211.                 SetPt(&aPoint, kDILeft, kDITop);
  212.                 err = DIBadMount(aPoint, event->message);
  213.             }
  214.             break;
  215.         case kOSEvent:
  216.             break;
  217.     }
  218. } /*DoEvent*/
  219.  
  220.  
  221. /*    Get the global coordinates of the mouse. When you call OSEventAvail
  222.     it will return either a pending event or a null event. In either case,
  223.     the where field of the event record will contain the current position
  224.     of the mouse in global coordinates and the modifiers field will reflect
  225.     the current state of the modifiers. Another way to get the global
  226.     coordinates is to call GetMouse and LocalToGlobal, but that requires
  227.     being sure that thePort is set to a valid port. */
  228.  
  229. #pragma segment Main
  230. void GetGlobalMouse(mouse)
  231.     Point    *mouse;
  232. {
  233.     EventRecord    event;
  234.     
  235.     OSEventAvail(kNoEvents, &event);    /* we aren't interested in any events */
  236.     *mouse = event.where;                /* just the mouse position */
  237. } /*GetGlobalMouse*/
  238.  
  239.  
  240. /*    Enable and disable menus based on the current state.
  241.     The user can only select enabled menu items. We set up all the menu items
  242.     before calling MenuSelect or MenuKey, since these are the only times that
  243.     a menu item can be selected. Note that MenuSelect is also the only time
  244.     the user will see menu items. This approach to deciding what enable/
  245.     disable state a menu item has the advantage of concentrating all
  246.     the decision-making in one routine, as opposed to being spread throughout
  247.     the application. Other application designs may take a different approach
  248.     that is just as valid. */
  249.  
  250. #pragma segment Main
  251. void AdjustMenus()
  252. {
  253.     WindowPtr    window;
  254.     MenuHandle    menu;
  255.  
  256.     window = FrontWindow();
  257.  
  258.     menu = GetMHandle(mFile);
  259.  
  260.     if ( IsDAWindow(window) ) {        /* we can allow desk accessories to be closed from the menu */
  261.         DisableItem(menu, iNew);
  262.         DisableItem(menu, iOpen);
  263.         DisableItem(menu, iSave);
  264.         DisableItem(menu, iSaveAs);
  265.         DisableItem(menu, iRevert);
  266.         DisableItem(menu, iPageSetup);
  267.         DisableItem(menu, iPrint);
  268.         EnableItem(menu, iClose);
  269.     }
  270.     else {
  271.         EnableItem(menu, iPageSetup);
  272.         EnableItem(menu, iPrint);
  273.     }
  274.  
  275.     menu = GetMHandle(mEdit);
  276.     if ( IsDAWindow(window) ) {        /* a desk accessory might need the edit menu… */
  277.         EnableItem(menu, iUndo);
  278.         EnableItem(menu, iCut);
  279.         EnableItem(menu, iCopy);
  280.         EnableItem(menu, iClear);
  281.         EnableItem(menu, iPaste);
  282.     } else {                        /* …but we don’t use it */
  283.         DisableItem(menu, iUndo);
  284.         DisableItem(menu, iCut);
  285.         DisableItem(menu, iCopy);
  286.         DisableItem(menu, iClear);
  287.         DisableItem(menu, iPaste);
  288.     }
  289.  
  290.     menu = GetMHandle(mPrGeneral);
  291.     if ( gPrGeneralLives) 
  292.     {    
  293.         //  If the particular opcode is supported by the current printer driver,
  294.         //  enable the menu item, otherwise dis-able it....
  295.     
  296.         if (gLandscapeOpImpl) 
  297.              EnableItem(menu, iCheckForLandscape);
  298.         else
  299.           {
  300.               CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
  301.             DisableItem(menu, iCheckForLandscape);
  302.           }
  303.  
  304.         if (gSetRslOpImpl) 
  305.              EnableItem(menu, iTurnHighResOFF);
  306.         else
  307.           {
  308.               CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
  309.             DisableItem(menu, iTurnHighResOFF);
  310.           }
  311.  
  312.         if (gDraftBitsOpImpl) 
  313.              EnableItem(menu, iUseDraftBits);
  314.         else 
  315.           {
  316.               CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
  317.             DisableItem(menu, iUseDraftBits);
  318.           }
  319.     } 
  320.     else {
  321.         CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
  322.         DisableItem(menu, iTurnHighResOFF);
  323.         
  324.         CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
  325.         DisableItem(menu, iUseDraftBits);
  326.         
  327.         CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
  328.         DisableItem(menu, iCheckForLandscape);
  329.     }
  330.  
  331. } /*AdjustMenus*/
  332.  
  333.  
  334. /*    This is called when an item is chosen from the menu bar (after calling
  335.     MenuSelect or MenuKey). It performs the right operation for each command.
  336.     It is good to have both the result of MenuSelect and MenuKey go to
  337.     one routine like this to keep everything organized. */
  338.  
  339. #pragma segment Main
  340. void DoMenuCommand(menuResult)
  341.     long        menuResult;
  342. {
  343.     short        menuID;                /* the resource ID of the selected menu */
  344.     short        menuItem;            /* the item number of the selected menu */
  345.     short        itemHit,
  346.                 printErr = 0;
  347.     Str255        daName;
  348.     short        daRefNum;
  349.     Boolean        handledByDA;
  350.     
  351.     menuID = HiWord(menuResult);    /* use macros for efficiency to... */
  352.     menuItem = LoWord(menuResult);    /* get menu item number and menu number */
  353.     switch ( menuID ) {
  354.         case mApple:
  355.             switch ( menuItem ) {
  356.                 case iAbout:        /* bring up alert for About */
  357.                     itemHit = Alert(rAboutAlert, nil);
  358.                     break;
  359.                 default:            /* all non-About items in this menu are DAs */
  360.                     /* type Str255 is an array in MPW 3 */
  361.                     GetItem(GetMHandle(mApple), menuItem, daName);
  362.                     daRefNum = OpenDeskAcc(daName);
  363.                     break;
  364.             }
  365.             break;
  366.         case mFile:
  367.             switch ( menuItem ) {
  368.                 case iNew:
  369.                     break;
  370.                 case iOpen:
  371.                     break;
  372.                 case iSave:
  373.                     break;
  374.                 case iClose:
  375.                     break;
  376.                 case iPageSetup:
  377.                     PresentStyleDialog();
  378.                     break;
  379.                 case iPrint:
  380.                     PrintThis();
  381.                     break;
  382.                 case iQuit:
  383.                     Terminate();
  384.                     break;
  385.             }
  386.             break;
  387.         case mEdit:                    /* call SystemEdit for DA editing & MultiFinder */
  388.             handledByDA = SystemEdit(menuItem-1);    /* since we don’t do any Editing */
  389.             break;
  390.         case mPrGeneral:
  391.             switch ( menuItem ) {
  392.                 case iTurnHighResOFF:
  393.                      {
  394.                        PrOpen ();
  395.                         if (PrError () == noErr)
  396.                          {
  397.                           if (!gHighResolutionON)
  398.                             {
  399.                                gHighResolutionON = true;
  400.                               CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, true);
  401.                              
  402.                               doSetRsl();
  403.                             }
  404.                            else
  405.                              {
  406.                                gHighResolutionON = false;
  407.                               CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
  408.                              
  409.                               resetSetRsl();
  410.                              }
  411.                          }
  412.                          else printErr = PrError ();
  413.                          
  414.                        PrClose ();
  415.                         
  416.                         if (printErr != noErr)  AlertUser ();
  417.                       }
  418.                     break;
  419.                 case iUseDraftBits:
  420.                      {
  421.                        PrOpen ();
  422.                         if (PrError () == noErr)
  423.                          {
  424.                           if (!gUseDraftBits)
  425.                             {
  426.                                gUseDraftBits = true;
  427.                               CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, true);
  428.                               
  429.                               doDraftBits ();
  430.                              }
  431.                           else
  432.                             {
  433.                                gUseDraftBits = false;
  434.                               CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
  435.                               
  436.                               doNODraftBits ();
  437.                              }
  438.                          
  439.                          }
  440.                          else printErr = PrError ();
  441.                          
  442.                        PrClose ();
  443.                         
  444.                        if (printErr != noErr)  AlertUser ();
  445.                      }
  446.                     break;
  447.                 case iCheckForLandscape:
  448.                      {
  449.                         if (!gCheckForLandscape)
  450.                           {
  451.                                gCheckForLandscape = true;
  452.                               CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, true);
  453.                           }
  454.                          else
  455.                             {
  456.                                gCheckForLandscape = false;
  457.                               CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
  458.                             }
  459.                      }
  460.                     break;
  461.             }
  462.             break;
  463.     }
  464.     HiliteMenu(0);                    /* unhighlight what MenuSelect (or MenuKey) hilited */
  465. } /*DoMenuCommand*/
  466.  
  467.  
  468. /* Clean up the application and exit. We close all of the windows so that
  469.  they can update their documents, if any. */
  470.  
  471. #pragma segment Main
  472. void Terminate()
  473. {
  474.     if (gPrRecHdl != nil)    
  475.       DisposHandle ((Handle) gPrRecHdl);     // Dispose of the print record
  476.     
  477.     ExitToShell();
  478.     
  479. } /*Terminate*/
  480.  
  481.  
  482.  
  483. /*    1.01 - The code that used to be part of ForceEnvirons has been moved into
  484.     this module. If an error is detected, instead of merely doing an ExitToShell,
  485.     which leaves the user without much to go on, we call AlertUser, which puts
  486.     up a simple alert that just says an error occurred and then calls ExitToShell.
  487.     Since there is no other cleanup needed at this point if an error is detected,
  488.     this form of error- handling is acceptable. If more sophisticated error recovery
  489.     is needed, an exception mechanism, such as is provided by Signals, can be used. */
  490.  
  491. #pragma segment Initialize
  492. void Initialize()
  493. {
  494.     Handle        menuBar;
  495.     long        total, contig;
  496.     EventRecord event;
  497.     short        count,
  498.                 myPrintErr;
  499.                 
  500.     InitGraf((Ptr) &qd.thePort);
  501.     InitFonts();
  502.     InitWindows();
  503.     InitMenus();
  504.     TEInit();
  505.     InitDialogs(nil);
  506.     InitCursor();
  507.     
  508.     MaxApplZone(); MoreMasters(); MoreMasters;
  509.  
  510.     for (count = 1; count <= 3; count++)
  511.         EventAvail(everyEvent, &event);
  512.     
  513.      
  514.     SysEnvirons(kSysEnvironsVersion, &gMac);
  515.     
  516.     
  517.     if (gMac.machineType < 0) AlertUser();
  518.     
  519.  
  520.     // We need the GWorld stuff (i.e. 32-bit QD) when printing in "draft" mode...
  521.     if (gMac.hasColorQD)
  522.     {
  523.       // Check to make sure the 32-Bit QuickDraw trap exists
  524.       if (NGetTrapAddress(QD32Trap, ToolTrap) ==  GetTrapAddress(Unimplemented))
  525.         QD32BitAlertUser();
  526.      }
  527.     else  QD32BitAlertUser();
  528.     
  529.     
  530.     gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
  531.  
  532.     if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) AlertUser();
  533.     
  534.     
  535.     PurgeSpace(&total, &contig);
  536.     if (total < kMinSpace) AlertUser();
  537.     
  538.  
  539.     menuBar = GetNewMBar(rMenuBar);            /* read menus into menu bar */
  540.     if ( menuBar == nil ) AlertUser();
  541.     SetMenuBar(menuBar);                    /* install menus */
  542.     DisposHandle(menuBar);
  543.     AddResMenu(GetMHandle(mApple), 'DRVR');    /* add DA names to Apple menu */
  544.     DrawMenuBar();
  545.     
  546.     /**
  547.         Initialize these booleans to enable the print loop (in PrGeneralPlayPrint.c)
  548.         to determine which PrGeneral opcodes should be used at print time.
  549.      **/
  550.     gHighResolutionON = false;   
  551.     gUseDraftBits = false;
  552.     gCheckForLandscape = false;
  553.     gDraftBitsHasBeenSet = false;
  554.     
  555.     /**
  556.         We will assume at this point that all of PrGeneral's opcodes are supported.
  557.         When we make a call for a particular opcode, we will check to make sure that 
  558.         the opcode is supported.  If it is NOT, the appropraite flag will be set to false
  559.         and that opcode will not be called until the printer driver is changed.
  560.     **/
  561.     gLandscapeOpImpl = true;
  562.     gDraftBitsOpImpl = true;
  563.     gSetRslOpImpl = true;
  564.  
  565.     /**
  566.         Create & initialize the print record....
  567.      **/
  568.      myPrintErr = 0;
  569.      gPrRecHdl = (THPrint) NewHandle(sizeof(TPrint));
  570.  
  571.  
  572.      if (MemError() == noErr && gPrRecHdl != nil)
  573.       {
  574.        PrOpen(); 
  575.         if (PrError() == noErr)
  576.           {
  577.            PrintDefault (gPrRecHdl);
  578.     
  579.            // We need to save the version number of the current printer driver.  This will enable
  580.            // us to compare the version of the printer driver when the user chooses a different
  581.            // printer driver via the Chooser.  This important because some earlier versions of 
  582.            // Apple's printers drivers did not support PrGeneral.  Which is the case for the 
  583.            // ImageWriter v2.5 and LaserWriter v4.0 and earlier.
  584.  
  585.            gOriginalDriverVers = PrDrvrVers ();
  586.            
  587.            if (PrError () == noErr)
  588.              gPrGeneralLives = testForPrGeneral ();  // Check to see if the current printer driver 
  589.             else myPrintErr = PrError ();             // supports PrGeneral and set the global flag...
  590.            }
  591.         else myPrintErr = PrError ();    // Grab the error before we close the Print Manager
  592.        PrClose();
  593.       
  594.        if (myPrintErr != 0)  
  595.          AlertUser ();
  596.       }
  597.      else  AlertUser ();
  598.      
  599. } /*Initialize*/
  600.  
  601.  
  602. /* Check to see if a window belongs to a desk accessory. */
  603.  
  604. #pragma segment Main
  605. Boolean IsDAWindow(window)
  606.     WindowPtr    window;
  607. {
  608.     if ( window == nil )
  609.         return false;
  610.     else    /* DA windows have negative windowKinds */
  611.         return ((WindowPeek) window)->windowKind < 0;
  612. } /*IsDAWindow*/
  613.  
  614.  
  615. /*    Check to see if a given trap is implemented. This is only used by the
  616.     Initialize routine in this program, so we put it in the Initialize segment.
  617.     The recommended approach to see if a trap is implemented is to see if
  618.     the address of the trap routine is the same as the address of the
  619.     Unimplemented trap. */
  620. /*    1.02 - Needs to be called after call to SysEnvirons so that it can check
  621.     if a ToolTrap is out of range of a pre-MacII ROM. */
  622.  
  623. #pragma segment Initialize
  624. Boolean TrapAvailable(tNumber,tType)
  625.     short        tNumber;
  626.     TrapType    tType;
  627. {
  628.     if ( ( tType == ToolTrap ) &&
  629.         ( gMac.machineType > envMachUnknown ) &&
  630.         ( gMac.machineType < envMacII ) ) {        /* it's a 512KE, Plus, or SE */
  631.         tNumber = tNumber & 0x03FF;
  632.         if ( tNumber > 0x01FF )                    /* which means the tool traps */
  633.             tNumber = _Unimplemented;            /* only go to 0x01FF */
  634.     }
  635.     return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
  636. } /*TrapAvailable*/
  637.  
  638.  
  639.  
  640. /*    Display an alert that tells the user an error occurred, then exit the program.
  641.     This routine is used as an ultimate bail-out for serious errors that prohibit
  642.     the continuation of the application. Errors that do not require the termination
  643.     of the application should be handled in a different manner. Error checking and
  644.     reporting has a place even in the simplest application. The error number is used
  645.     to index an 'STR#' resource so that a relevant message can be displayed. */
  646.  
  647. #pragma segment Main
  648. void AlertUser()
  649. {
  650.     short        itemHit;
  651.  
  652.     SetCursor(&qd.arrow);
  653.     itemHit = Alert(rUserAlert, nil);
  654.     ExitToShell();
  655. } /* AlertUser */
  656.  
  657.  
  658.     
  659. // Display an alert to tell the user that 32-bit QuickDraw is required to 
  660. // run PrGeneral Play...
  661.  
  662. #pragma segment Main
  663. void QD32BitAlertUser()
  664. {
  665.     short        itemHit;
  666.  
  667.     SetCursor(&qd.arrow);
  668.     
  669.     itemHit = Alert(r32BitQDAlert, nil);
  670.     ExitToShell();
  671. }  // end of QD32BitAlertUser
  672.     
  673.  
  674.     
  675.